#include <mailbox.h>
#include <string.h>
#include <sys/syscall.h>

box_t box[BOXS];
int avaliable_box = 0;

mailbox_t mbox_open(char *name)
{
    // TODO:
    for(int i = 0; i < avaliable_box; i++)
        if(!strcmp(box[i].name, name))
            return i;
    strcpy(box[avaliable_box].name, name);
    box[avaliable_box].count = 0;
    mthread_mutex_init(&box[avaliable_box].lock);
    mthread_cond_init(&box[avaliable_box].empty);
    mthread_cond_init(&box[avaliable_box].full);
    avaliable_box++;
    return (avaliable_box - 1);
}

void mbox_close(mailbox_t mailbox)
{
    // TODO:
    if(box[mailbox].count == 0){
        mthread_mutex_destroy(&box[avaliable_box].lock);
        mthread_cond_destroy(&box[avaliable_box].empty);
        mthread_cond_destroy(&box[avaliable_box].full);
    }
}

void mbox_send(mailbox_t mailbox, void *msg, int msg_length)
{
    // TODO:
    mthread_mutex_lock(&box[mailbox].lock);
    while(box[mailbox].count == 2)
        mthread_cond_wait(&box[mailbox].full, &box[mailbox].lock);
    sys_send_mailbox(mailbox, msg, msg_length);
    box[mailbox].count++;
    mthread_cond_signal(&box[mailbox].empty);
    mthread_mutex_unlock(&box[mailbox].lock);
}

void mbox_recv(mailbox_t mailbox, void *msg, int msg_length)
{
    // TODO:
    mthread_mutex_lock(&box[mailbox].lock);
    while(box[mailbox].count == 0)
        mthread_cond_wait(&box[mailbox].empty, &box[mailbox].lock);
    sys_recv_mailbox(mailbox, msg, msg_length);
    box[mailbox].count--;
    mthread_cond_signal(&box[mailbox].full);
    mthread_mutex_unlock(&box[mailbox].lock);
}
